package com.nulldev.util.concurrency.threadIt.v4.executors.fje.utils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import com.nulldev.util.concurrency.threadIt.v4.executors.fje.interfaces.ThreadPicker;
import com.nulldev.util.data.Variables;

public class CircularThreadPicker<T extends Thread> implements ThreadPicker<T> {

	private final List<T> threads;
	private final AtomicInteger position;

	public CircularThreadPicker(final List<T> threads) {
		this.threads = Variables.requireNonNullObject(threads, "threads");
		this.position = new AtomicInteger(0);
	}

	@Override
	public T nextThread() {
		try {
			if (this.position.get() >= this.threads.size())
				this.position.lazySet(0);
			final T t = this.threads.get(this.position.getAndIncrement());
			return t;
		} catch (IndexOutOfBoundsException aioe) {
			try {
				if (this.threads.size() < 2)
					return this.nextThread();
				else {
					this.position.lazySet(1);
					// try again lol
					return this.threads.get(0);
				}
			} catch (Exception ex) {
				return nextThread();
			}
		} catch (Exception ex) {
			return nextThread();
		}
	}

}
